/**
 * @file   USB2XXX_CANFD_SchTest.cpp
 * @brief  调度表模式发送数据测试程序
 * @author wdluo(wdluo@toomoss.com)
 * @version 1.0
 * @date 2022-12-03
 * @copyright Copyright (c) 2022 重庆图莫斯电子科技有限公司
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "offline_type.h"
#include "usb_device.h"
#include "usb2canfd.h"
#if _WIN32
#include <windows.h>
#pragma comment(lib,"USB2XXX.lib")
#endif
//在运行程序之前需要将CAN1和CAN2对接后才能有正确的结果出现
int main(int argc, const char* argv[])
{
    DEVICE_INFO DevInfo;
    int DevHandle[10];
    int SendCANIndex = 0;   //0-CAN1,1-CAN2
    int ReceiveCANIndex = 1;//0-CAN1,1-CAN2
    bool state;
    int ret;
    //扫描连接到电脑的设备，并获取设备号
    ret = USB_ScanDevice(DevHandle);
    if(ret <= 0){
        printf("No device connected!\n");
        return 0;
    }
    //打开设备
    state = USB_OpenDevice(DevHandle[0]);
    if(!state){
        printf("Open device error!\n");
        return 0;
    }
    char FunctionStr[256]={0};
    //获取设备固件信息
    state = DEV_GetDeviceInfo(DevHandle[0],&DevInfo,FunctionStr);
    if(!state){
        printf("Get device infomation error!\n");
        return 0;
    }else{
        printf("Firmware Info:\n");
	    printf("Firmware Name:%s\n",DevInfo.FirmwareName);
        printf("Firmware Build Date:%s\n",DevInfo.BuildDate);
        printf("Firmware Version:v%d.%d.%d\n",(DevInfo.FirmwareVersion>>24)&0xFF,(DevInfo.FirmwareVersion>>16)&0xFF,DevInfo.FirmwareVersion&0xFFFF);
        printf("Hardware Version:v%d.%d.%d\n",(DevInfo.HardwareVersion>>24)&0xFF,(DevInfo.HardwareVersion>>16)&0xFF,DevInfo.HardwareVersion&0xFFFF);
    }
    //获取波特率参数并初始化配置CAN
    CANFD_INIT_CONFIG CANFDConfig;
    ret = CANFD_GetCANSpeedArg(DevHandle[0],&CANFDConfig,500000,2000000);
    if(ret != CANFD_SUCCESS){
        printf("CANFD Get Speed Error!\n");
        return 0;
    }else{
        printf("CANFD Get Speed Success!\n");
    }
    CANFDConfig.ISOCRCEnable = 1;//设置CANFD校验模式
    CANFDConfig.ResEnable = 1;   //是否使能适配器内部120欧终端电阻，若需要使能则设置为1，否则设置为0
    ret = CANFD_Init(DevHandle[0],SendCANIndex,&CANFDConfig);
    if(ret != CANFD_SUCCESS){
        printf("CANFD Init Error!\n");
        return 0;
    }else{
        printf("CANFD Init Success!\n");
    }
    ret = CANFD_Init(DevHandle[0],ReceiveCANIndex,&CANFDConfig);
    if(ret != CANFD_SUCCESS){
        printf("CANFD Init Error!\n");
        return 0;
    }else{
        printf("CANFD Init Success!\n");
    }
    //启动接收数据
    ret = CANFD_StartGetMsg(DevHandle[0],ReceiveCANIndex);
    if(ret == CANFD_SUCCESS){
        printf("Start CAN  Success\n");
    }else{
        printf("Start CAN  Error ret = %d\n", ret);
        return 0;
    }
    //准备需要发送的帧
    const int AllMsgNum = 20;
    CANFD_MSG CanMsg[AllMsgNum];
    for (int i = 0; i < AllMsgNum; i++){
        CanMsg[i].Flags = 0;//bit[0]-BRS,bit[1]-ESI,bit[2]-FDF,bit[6..5]-Channel,bit[7]-RXD
        CanMsg[i].DLC = 8;
        CanMsg[i].ID = 0x123|CANFD_MSG_FLAG_IDE;
        for (int j = 0; j < CanMsg[i].DLC; j++){
            CanMsg[i].Data[j] = j;
        }
        CanMsg[i].Data[0] = i;
        CanMsg[i].TimeStamp = 100;//帧间隔时间为100ms
    }
    //配置为1个调度表，表里面包含AllMsgNum帧数据
    uint8_t MsgTabNum[1]={AllMsgNum};
    //配置调度表发送次数为1，0xFFFF为一直循环发送，除非调用停止调度表后才会停止
    uint16_t SendTimes[1]={3};
    ret = CANFD_SetSchedule(DevHandle[0], SendCANIndex,CanMsg,MsgTabNum,SendTimes,1);//设置调度表
    if(ret == CANFD_SUCCESS){
        printf("Set CAN Schedule Success\n");
    }else{
        printf("Set CAN Schedule Error ret = %d\n", ret);
        return 0;
    }
    ret = CANFD_StartSchedule(DevHandle[0],SendCANIndex,0,10,0);//启动调度表
    if(ret == CANFD_SUCCESS){
        printf("Start CAN Schedule 1 Success\n");
    }else{
        printf("Start CAN Schedule 1 Error ret = %d\n", ret);
        return 0;
    }
    
    //从另外一个通道读取数据
    int t=300;
    while(t--){//循环读取
        CANFD_MSG CanMsgBuffer[1024];
        int GetMsgNum = CANFD_GetMsg(DevHandle[0],ReceiveCANIndex,CanMsgBuffer,1024);
        if (GetMsgNum > 0){
            for (int i = 0; i < GetMsgNum; i++){
                uint64_t tus = ((((uint64_t)CanMsgBuffer[i].TimeStampHigh<<32)|CanMsgBuffer[i].TimeStamp)*10.0);
                printf("CanMsg[%d].ID = 0x%08X\n", i, CanMsgBuffer[i].ID & CANFD_MSG_FLAG_ID_MASK);
                printf("CanMsg[%d].TimeStamp = %.6f s\n", i, tus/1000000.0);
                printf("CanMsg[%d].Data = ", i);
                for (int j = 0; j < CanMsgBuffer[i].DLC; j++)
                {
                    printf("0x%02X ", CanMsgBuffer[i].Data[j]);
                }
                printf("\n");
            }
        }
#if _WIN32
        Sleep(100);
#else
        usleep(100*1000);
#endif
    }
    ret = CANFD_StopSchedule(DevHandle[0], SendCANIndex);
    if(ret == CANFD_SUCCESS){
        printf("Stop CAN Schedule Success\n");
    }else{
        printf("Stop CAN Schedule Error ret = %d\n", ret);
        return 0;
    }
    USB_CloseDevice(DevHandle[0]);
    return 0;
}

